package ace.module.captcha.core.impl.manager.impl;

import ace.cmp.core.constants.CoreConstant;
import ace.cmp.core.utils.SystemClockUtils;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.spring.AbstractSpringDtoManager;
import ace.cmp.i18n.api.MessageSourceAssertService;
import ace.module.captcha.api.constant.CaptchaConstant;
import ace.module.captcha.api.enums.CaptchaApplicationStatusEnum;
import ace.module.captcha.api.model.dto.CaptchaApplicationDto;
import ace.module.captcha.core.impl.dao.entity.CaptchaApplication;
import ace.module.captcha.core.impl.dao.repository.CaptchaApplicationRepository;
import ace.module.captcha.core.impl.manager.CaptchaApplicationManager;
import ace.module.captcha.core.impl.manager.repository.CaptchaApplicationMgrRepository;
import ace.module.common.api.constant.CommonConstants;
import ace.module.common.core.impl.properties.ModuleCommonBaseProperties;
import ace.module.common.core.impl.properties.ModuleCommonSecurityProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 图形验证码应用 spring data jdbc querydsl rsql manager implement.
 *
 * @author Caspar
 */
@Slf4j
@AllArgsConstructor
@Component
public class CaptchaApplicationManagerImpl
    extends AbstractSpringDtoManager<CaptchaApplication, Long, CaptchaApplicationDto>
    implements CaptchaApplicationManager {

  private final MessageSourceAssertService assertService;
  private final CaptchaApplicationMgrRepository captchaApplicationMgrRepository;
  private final CaptchaApplicationRepository captchaApplicationRepository;
  private final ModuleCommonBaseProperties moduleCommonBaseProperties;
  private final ModuleCommonSecurityProperties moduleCommonSecurityProperties;

  @Override
  public CaptchaApplication getById(Long id) {

    CaptchaApplication captchaApplication = this.captchaApplicationMgrRepository.getById(id);

    return captchaApplication;
  }

  @Override
  public CaptchaApplication getByIdAndCheckAll(Long id) {
    assertService.isNull(
        id, "captcha.captcha-biz-type.param-id-cannot-be-null", "captchaBizTypeId can't be null");

    CaptchaApplication captchaApplication = this.captchaApplicationMgrRepository.getById(id);

    this.check(captchaApplication);

    return captchaApplication;
  }

  @Override
  public CaptchaApplication getSystemDefault() {
    CaptchaApplication captchaApplication =
        this.captchaApplicationRepository.getByKey(
            CaptchaConstant.DEFAULT_CAPTCHA_APPLICATION_APP_KEY);
    if (captchaApplication != null) {
      return captchaApplication;
    }
    captchaApplication = this.createSystemDefaultInMemory();
    return captchaApplication;
  }

  @Override
  public CaptchaApplication getByKey(String key) {
    return this.captchaApplicationRepository.getByKeyAndDeleteFlag(
        key, CoreConstant.DELETE_FLAG_NOT);
  }

  @Override
  public CaptchaApplicationDto getDtoByKey(String key) {
    CaptchaApplication model =
        this.captchaApplicationRepository.getByKeyAndDeleteFlag(key, CoreConstant.DELETE_FLAG_NOT);
    return this.getEntityToDtoConverter().convert(model);
  }

  @Override
  public CaptchaApplicationDto getDtoAndCheckNotNullAdminApplication() {
    CaptchaApplication captchaApplication = this.getAdminApplication();
    this.checkNotNull(captchaApplication);
    return this.convertToEntityDto(captchaApplication);
  }

  @Override
  public CaptchaApplication getAdminApplication() {
    return this.getById(moduleCommonSecurityProperties.getCaptchaAdminAppId());
  }


  private CaptchaApplication createSystemDefaultInMemory() {
    return CaptchaApplication.builder()
        .id(moduleCommonSecurityProperties.getCaptchaAdminAppId())
        .name("系统默认配置")
        .remark("系统默认配置")
        .key(CaptchaConstant.DEFAULT_CAPTCHA_APPLICATION_APP_KEY)
        .status(CaptchaApplicationStatusEnum.NORMAL.getCode())
        .deleteFlag(CoreConstant.DELETE_FLAG_NOT)
        .createTime(SystemClockUtils.currentTimeMillis())
        .updateTime(SystemClockUtils.currentTimeMillis())
        .rowVersion(null)
        .build();
  }

  private void check(CaptchaApplication captchaApplication) {

    this.checkNotNull(captchaApplication);

    assertService.isFalse(
        CaptchaApplicationStatusEnum.NORMAL.getCode().equals(captchaApplication.getStatus()),
        "captcha.captcha-biz-type.is-locked",
        "图形应用不存在已锁定");

    assertService.isFalse(
        CommonConstants.DEFAULT_DELETE_FLAG_NOT.equals(captchaApplication.getDeleteFlag()),
        "captcha.captcha-biz-type.is-deleted",
        "图形应用不存在");
  }

  private void checkNotNull(CaptchaApplication captchaApplication) {
    assertService.isNull(captchaApplication, "captcha.captcha-biz-type.data-not-exist", "图形应用不存在");

  }
}
